package libs

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

func getAvailableDirsFromServer() ([]string, error) {
	resp, err := http.Get(Config.RemoteReceiver + "EditToServer.php?machine_id=" + GetMachineID() + "&action=list&key=" + GenerateKey())
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusNotFound {
		return nil, fmt.Errorf("remote_receiver 配置错误， 404")
	}

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("非预期状态码: %d", resp.StatusCode)
	}

	bodyBytes, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应体失败: %v", err)
	}

	// 解码 base64
	decodedBytes, err := base64.StdEncoding.DecodeString(string(bodyBytes))
	if err != nil {
		return nil, fmt.Errorf("通信对接失败,请不要修改EditToServer.php文件: %v", string(bodyBytes))
	}

	// 移除 AUTH_KEY
	authKey := GenerateKey()
	decodedString := string(decodedBytes)
	jsonString := strings.TrimPrefix(strings.TrimSuffix(decodedString, string(authKey)), string(authKey))

	var dirs []string
	err = json.Unmarshal([]byte(jsonString), &dirs)
	if err != nil {
		return nil, fmt.Errorf("通信对接失败,请不要修改EditToServer.php文件: %v", err)
	}

	// 反转数组
	for i, j := 0, len(dirs)-1; i < j; i, j = i+1, j-1 {
		dirs[i], dirs[j] = dirs[j], dirs[i]
	}

	return dirs, nil
}

func sendDeleteRequestToRemote(filePath string) {
	relPath, err := filepath.Rel(Config.LocalPath, filePath)
	if err != nil {
		DebugPrint("获取相对路径失败: %v\n", err)
		return
	}

	posturl := Config.RemoteReceiver

	data := url.Values{}
	data.Set("action", "REMOVE")
	data.Set("path", filepath.Join(Config.RemotePath, relPath))

	resp, err := http.PostForm(posturl+"EditToServer.php?machine_id="+GetMachineID()+"&key="+GenerateKey(), data)
	if err != nil {
		DebugPrint("发送删除请求失败: %v\n", err)
		return
	}
	defer resp.Body.Close()

	bodyBytes, err := io.ReadAll(resp.Body)
	if err != nil {
		DebugPrint("读取响应体失败: %v\n", err)
		return
	}
	bodyString := string(bodyBytes)

	fmt.Printf("【REMOVE】["+relPath+"]  ===>  %s\n", bodyString)
}

func sendFileToRemote(path string, isDir bool, isCreate bool) {
	relPath, err := filepath.Rel(Config.LocalPath, path)
	if err != nil {
		DebugPrint("获取相对路径失败: %v\n", err)
		return
	}

	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)

	if !isDir {
		time.Sleep(time.Microsecond * 100)
		file, err := os.Open(path)
		if err != nil {
			DebugPrint("打开文件失败: %v\n", err)
			return
		}
		defer file.Close()

		part, err := writer.CreateFormFile("file", filepath.Base(path))
		if err != nil {
			DebugPrint("创建表单文件失败: %v\n", err)
			return
		}
		_, err = io.Copy(part, file)
		if err != nil {
			DebugPrint("复制文件内容失败: %v\n", err)
			return
		}
	} else {
		// 检查文件夹名称是否包含 "---"
		if strings.Contains(filepath.Base(path), "---") {
			return
		}
		// ... 其他处理目录的代码 ...
	}

	var action string
	if isCreate {
		action = "CREATE"
	} else {
		action = "MODIFY"
	}

	writer.WriteField("action", action)
	writer.WriteField("path", filepath.Join(Config.RemotePath, relPath))
	writer.WriteField("is_dir", strconv.FormatBool(isDir))
	writer.Close()

	req, err := http.NewRequest("POST", Config.RemoteReceiver+"EditToServer.php?machine_id="+GetMachineID()+"&key="+GenerateKey(), body)
	if err != nil {
		DebugPrint("创建请求失败: %v\n", err)
		return
	}
	req.Header.Set("Content-Type", writer.FormDataContentType())

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		DebugPrint("发送请求失败: %v\n", err)
		return
	}
	defer resp.Body.Close()

	bodyBytes, err := io.ReadAll(resp.Body)
	if err != nil {
		DebugPrint("读取响应体失败: %v\n", err)
		return
	}
	bodyString := string(bodyBytes)

	fmt.Printf("【"+action+"】["+relPath+"]  ===>  %s\n", bodyString)
}

func sendRenameRequestToRemote(oldPath, newPath string) {
	relOldPath, err := filepath.Rel(Config.LocalPath, oldPath)
	if err != nil {
		DebugPrint("获取旧路径的相对路径失败: %v\n", err)
		return
	}

	relNewPath, err := filepath.Rel(Config.LocalPath, newPath)
	if err != nil {
		DebugPrint("获取新路径的相对路径失败: %v\n", err)
		return
	}

	isDirectory := isDir(newPath)

	if isDirectory {
		// 检查文件夹名称是否以三个连字符结尾
		dirName := filepath.Base(newPath)
		if strings.HasSuffix(dirName, "---") {
			// 去除文件夹名称后面的三个连字符
			newDirName := strings.TrimSuffix(dirName, "---")
			rePath := filepath.Join(filepath.Dir(newPath), newDirName)

			// 重命名文件夹
			if err := os.Rename(newPath, rePath); err != nil {
				DebugPrint("重命名文件夹失败: %v\n", err)
				return
			}
			// 递归上传文件夹内容
			uploadDirectory(rePath)
			return
		}
	}

	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)

	if !isDirectory {
		file, err := os.Open(newPath)
		if err != nil {
			DebugPrint("打开文件失败: %v\n", err)
			return
		}
		defer file.Close()

		part, err := writer.CreateFormFile("file", filepath.Base(newPath))
		if err != nil {
			DebugPrint("创建表单文件失败: %v\n", err)
			return
		}
		_, err = io.Copy(part, file)
		if err != nil {
			DebugPrint("复制文件内容失败: %v\n", err)
			return
		}
	}

	writer.WriteField("action", "RENAME")
	writer.WriteField("old_path", filepath.Join(Config.RemotePath, relOldPath))
	writer.WriteField("new_path", filepath.Join(Config.RemotePath, relNewPath))
	writer.WriteField("is_dir", strconv.FormatBool(isDirectory))
	writer.Close()

	req, err := http.NewRequest("POST", Config.RemoteReceiver+"EditToServer.php?machine_id="+GetMachineID()+"&key="+GenerateKey(), body)
	if err != nil {
		DebugPrint("创建请求失败: %v\n", err)
		return
	}
	req.Header.Set("Content-Type", writer.FormDataContentType())

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		DebugPrint("发送重命名请求失败: %v\n", err)
		return
	}
	defer resp.Body.Close()

	bodyBytes, err := io.ReadAll(resp.Body)
	if err != nil {
		DebugPrint("读取响应体失败: %v\n", err)
		return
	}
	bodyString := string(bodyBytes)
	fmt.Printf("【RENAME】["+relOldPath+"]  ===>  %s\n", bodyString)
}
